﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Pavilion.DesignerTool.ViewTools.ConnectableListBox;
using System.Windows;
using System.IO;

namespace Pavilion.DesignerTool.NodeDesignerTool.Scripting
{
    public class NodeLayoutSerializer
    {
        public XDocument SerializeCollection(IConnectableItem containerNode)
        {
            XDocument xmlDocument = new XDocument();
            xmlDocument.Add(new XElement("Script", SerializeContainer(containerNode)));

            return xmlDocument;
        }

        private XElement SerializeContainer(IConnectableItem containerNode)
        {
            XElement BaseWrapperXElement = SerializeNode(containerNode as NodeBaseWrapper);

            foreach (NodeBaseWrapper nodeWrapper in (containerNode as ContainerNodeWrapper).ConnectableItems)
            {
                if (nodeWrapper is IConnectableItemContainer)
                    BaseWrapperXElement.Add(SerializeContainer(nodeWrapper));
                else
                    BaseWrapperXElement.Add(SerializeNode(nodeWrapper));
            }

            return BaseWrapperXElement;
        }

        private XElement SerializeNode(NodeBaseWrapper nodeBaseWrapper)
        {
            XElement baseWrapperXElement = new XElement("Node");
            baseWrapperXElement.Add(CreateAttributesForNodeBase(nodeBaseWrapper));

            return baseWrapperXElement;
        }

        public IEnumerable<XAttribute> CreateAttributesForNodeBase(NodeBaseWrapper nodeBaseWrapper)
        {
            return new XAttribute[] { new XAttribute("Name", nodeBaseWrapper.Node.Name), new XAttribute("Position", nodeBaseWrapper.Position) };
        }

        public IEnumerable<XAttribute> CreateListofAttributesToDeserialize(IEnumerable<XElement> nodeXElementList) 
        {
            IEnumerable<XAttribute> listOfAttributes = new List<XAttribute>();

            foreach (XElement xElement in nodeXElementList)
            {
                foreach (XAttribute xAttribute in xElement.Attributes("Node"))
                    (listOfAttributes as List<XAttribute>).Add(xAttribute);
            }

            return listOfAttributes;
        }

        public void DeserializeCollection(IConnectableItem rootContainerNode, string nodeXmlListPath)
        {
            if (!File.Exists(nodeXmlListPath))
                return;

            XElement rootNodeElement = XDocument.Load(nodeXmlListPath).Element("Script").Element("Node");

            DeserializeNode(rootContainerNode, rootNodeElement);
        }

        private void DeserializeNode(IConnectableItem connectableItem, XElement nodeElement)
        {
            IList<double> points = ParseMulipleFloatNumbers(nodeElement.Attribute("Position").Value);
            connectableItem.Position = new Point(points[0], points[1]);

            IEnumerable<XElement> nodeXElementList = nodeElement.Elements("Node");

            foreach (XElement nodeElementItem in nodeXElementList)
            {
                string name = nodeElementItem.Attribute("Name").Value;

                IConnectableItem item = (connectableItem as ContainerNodeWrapper).GetNode(name);

                if (item != null)
                    DeserializeNode(item, nodeElementItem);
            }
        }

        private IList<double> ParseMulipleFloatNumbers(string multipleNumbers)
        {
            List<double> multipleNumbersList = new List<double>();

            foreach (string stringNumber in multipleNumbers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                multipleNumbersList.Add(double.Parse(stringNumber.Trim()));

            return multipleNumbersList.ToArray();
        }
    }
}
